package com.hex.ds.hdrs.period.task.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.hex.bigdata.hbda.base.Page;
import com.hex.bigdata.hbda.utils.FileUtil;
import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.app.service.AppManager;
import com.hex.ds.hdrs.app.service.AppSession;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.constant.ErrorCode;
import com.hex.ds.hdrs.common.excel.DownPeriodJobExcelHelper;
import com.hex.ds.hdrs.common.exception.BizException;
import com.hex.ds.hdrs.common.page.PageData;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.common.utils.MapUtil;
import com.hex.ds.hdrs.common.utils.SecToTimeUtil;
import com.hex.ds.hdrs.engine.manager.LstFinishManager;
import com.hex.ds.hdrs.engine.manager.RunningManager;
import com.hex.ds.hdrs.engine.manager.ToDoManager;
import com.hex.ds.hdrs.engine.manager.ToRunManager;
import com.hex.ds.hdrs.engine.service.DispatcherService;
import com.hex.ds.hdrs.engine.service.HandService;
import com.hex.ds.hdrs.engine.service.ProcessorService;
import com.hex.ds.hdrs.label.service.impl.LabelInfoServiceImpl;
import com.hex.ds.hdrs.period.job.dto.PeriodJobDto;
import com.hex.ds.hdrs.period.job.po.JobTask;
import com.hex.ds.hdrs.period.job.po.PeriodJob;
import com.hex.ds.hdrs.period.job.service.PeriodJobService;
import com.hex.ds.hdrs.period.task.converter.IDependPeriodTaskDtoConverter;
import com.hex.ds.hdrs.period.task.converter.IPeriodTaskConverter;
import com.hex.ds.hdrs.period.task.dao.PeriodTaskDao;
import com.hex.ds.hdrs.period.task.dao.PeriodTaskDefDao;
import com.hex.ds.hdrs.period.task.dto.PeriodTaskDto;
import com.hex.ds.hdrs.period.task.dto.depend.*;
import com.hex.ds.hdrs.period.task.po.PeriodTask;
import com.hex.ds.hdrs.period.task.po.PeriodTaskDef;
import com.hex.ds.hdrs.period.task.vo.PeriodTaskByEcharsVo;
import com.hex.ds.hdrs.period.task.vo.PeriodTaskVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Package: com.hex.ds.hdrs.period.task.service
 * @ClassName PeriodTaskService
 * @Description: 周期任务service
 * @Author: jd.chen
 * @Date 2021/7/8 15:18
 * @Version v1.0
 **/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class PeriodTaskService {

    private final PeriodTaskDao periodTaskDao;

    private final PeriodJobService periodJobService;

    private final HandService handService;

    @Autowired
    private LstFinishManager lstFinishManager;

    @Autowired
    private ToRunManager toRunManager;
    @Autowired
    private ToDoManager toDoManager;

    private final RunningManager runningManager;
    private final AppManager appManager;

    private final PeriodTaskDefService periodTaskDefService;

    private final PeriodTaskDefDao periodTaskDefDao;

    private final IDependPeriodTaskDtoConverter dependPeriodTaskDtoConverter;

    private final IPeriodTaskConverter converter;

    private final LabelInfoServiceImpl labelInfoService;
    private final DispatcherService dispatcherService;
    private final ProcessorService processorService;

    /*
     * @Method: queryListByPage <br>
     * @Param: [periodTaskDto, page] <br>
     * @Return: com.hex.ds.hdrs.common.page.PageData <br>
     * @Description：分页查询<br>
     * @Author： wz.li<br>
     * @Date： 2023/5/4 16:07 <br>
     * @Version： V2.0.2<br>
     */
    public PageData queryListByPage(PeriodTaskDto periodTaskDto, Page page) {
        List<PeriodTask> periodTasks = periodTaskDao.queryListByPage(converter.toPeriodTaskForQuery(periodTaskDto), page);
        return new PageData(periodTasks, page);
    }

    /*
     * @Method: queryList <br>
     * @Param: [periodTaskDto] <br>
     * @Return: java.util.List<com.hex.ds.hdrs.period.task.po.PeriodTask> <br>
     * @Description：不分页查询<br>
     * @Author： wz.li<br>
     * @Date： 2023/5/4 19:06 <br>
     * @Version： V2.0.2<br>
     */
    public List<PeriodTask> queryList(PeriodTaskDto periodTaskDto) {
        return periodTaskDao.queryList(converter.toPeriodTaskForQuery(periodTaskDto));
    }

    /**
     * 获取全量的toDo任务队列
     *
     * @return
     */
    public List<PeriodTask> qryToDoTaskList() {
        log.info("查询Task List【PeriodTaskService.qryToDoTaskList】====》");
        return this.periodTaskDao.qryToDoTaskList();
    }

    /**
     * 获取增量的任务队列
     *
     * @param lastQryTs
     * @return
     */
    public List<PeriodTask> qryToDoTaskList(String lastQryTs) {
        log.info("查询Task List【PeriodTaskService.qryToDoTaskList,参数【lastQryTs】:{}",lastQryTs);
        return this.periodTaskDao.qryToDoTaskList(lastQryTs);
    }

    /**
     * 获取全量--最新完成任务队列
     *
     * @return
     */
    public List<PeriodTask> qryLstFnsTaskList() {
        log.info("查询Task List【PeriodTaskService.qryLstFnsTaskList】====》");
        return this.periodTaskDao.qryLstFnsTaskList();
    }

    /**
     * 获取增量--最新完成任务队列
     *
     * @param lastQryTs
     * @return
     */
    public List<PeriodTask> qryLstFnsTaskList(String lastQryTs) {
        return this.periodTaskDao.qryLstFnsTaskList(lastQryTs);
    }

    public List<PeriodTask> qryTaskListInJob(String jobCode, String bizDate) {
        Map map = new HashMap(16);
        map.put("jobCode", jobCode);
        map.put("bizDate", bizDate);
        return this.qryPeriodTaskList(map);
    }

    /**
     * 检查任务上游依赖是否完成  true：未完成  false：已完成
     *
     * @param task
     * @return
     */
    public boolean checkUpJobIsFinish(PeriodTask task) {
        String bizDate = task.getBizDate();

        String dependJob = task.getDependJob();
        if (StringUtils.isNotEmpty(dependJob)) {
            String[] dependJobs = dependJob.split(",");
            Map<String, Object> map = new HashMap<>(16);
            // 20210617  jd.chen  不等于处理完成的作业
            map.put("jobStatus", Const.JOB_DO_SUCCESS);
            map.put("bizDate", bizDate);
            map.put("dependJobs", dependJobs);
            int dependJobCountNoStatus = this.periodJobService.upDependJobCountNoStatus(map);
            if (dependJobCountNoStatus != dependJobs.length) {
                log.debug("DB校验存在上游Job未生成实例");
                return true;
            }
            int dependJobCount = this.periodJobService.upDependJobCount(map);
            if (dependJobCount > 0) {
                log.debug("DB校验存在上游Job未完成【checkUpJobIsFinish】");
                return true;
            }
        }

        String dependTask = task.getDependTask();
        if (StringUtils.isNotEmpty(dependTask)) {
            String[] dependTasks = dependTask.split(",");
            Map<String, Object> map = new HashMap<>(16);
            map.put("bizDate", bizDate);
            map.put("dependTasks", dependTasks);
            int dependTaskCountNoStatus = this.upDependTaskCountNoStatus(map);
            if (dependTaskCountNoStatus != dependTasks.length) {
                log.debug("DB校验存在上游TASK未生成实例");
                return true;
            }
            int dependTaskCount = this.upDependTaskCount(map);
            if (dependTaskCount > 0) {
                log.debug("DB校验存在上游Task未完成【checkUpJobIsFinish】");
                return true;
            }
        }

        return false;
    }

    public List<PeriodTask> upDependTaskList(PeriodTask task){
        List<PeriodTask> upDependList = null;
        String bizDate = task.getBizDate();
        String dependTask = task.getDependTask();
        if (StringUtils.isNotEmpty(dependTask)) {
            String[] dependTasks = dependTask.split(",");
            Map<String, Object> map = new HashMap<>(16);
            map.put("bizDate", bizDate);
            map.put("dependTasks", dependTasks);
            upDependList = this.queryUpDependTask(map);
        }
        return upDependList;
    }

    public List<PeriodJob> upDependJobList(PeriodTask task){
        String bizDate = task.getBizDate();
        List<PeriodJob> periodJobList = null;
        String dependJob = task.getDependJob();
        if (StringUtils.isNotEmpty(dependJob)) {
            String[] dependJobs = dependJob.split(",");
            Map<String, Object> map = new HashMap<>(16);
//            map.put("jobStatus", Const.JOB_DO_SUCCESS);
            map.put("bizDate", bizDate);
            map.put("dependJobs", dependJobs);
            periodJobList = this.periodJobService.queryUpDependJob(map);
        }
        return periodJobList;
    }

    /**
     * 查询上游任务数(包含状态条件)
     *
     * @param map
     * @return
     */
    public int upDependTaskCount(Map map) {
        return periodTaskDao.upDependTaskCount(map);
    }


    public List<PeriodTask> queryUpDependTask(Map map){
        return periodTaskDao.queryUpDependTask(map);
    }

    /**
     * 查询上游任务数(不包含状态条件)
     *
     * @param map
     * @return
     */
    public int upDependTaskCountNoStatus(Map map) {
        return periodTaskDao.upDependTaskCountNoStatus(map);
    }

    public void add(PeriodTask periodTask) {
        periodTaskDao.insert(periodTask);
    }

    /**
     * 更新任务
     *
     * @param map
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int updateTask(Map map) {
        log.info("【PeriodTaskService.updateTask】map:{}", map);
        return periodTaskDao.updateByMap(map);
    }

    /**
     * @Method: upTaskToDo
     * @Param: [pkId]
     * @Return: void
     * @Description： 更新任务到待处理
     * @Author： jd.chen
     * @Date： 2021/6/21 20:04
     * @Version： V1.0
     */
    public void upTaskToDo(String pkId, String upTs) {
        Map taskMap = new HashMap(16);
        taskMap.put("taskStatus", Const.TASK_TODO_RUN);
        taskMap.put("execStTs", " ");
        taskMap.put("execEndTs", " ");
        taskMap.put("taskExecLog", " ");
        taskMap.put("trackJson", " ");
        taskMap.put("pkId", pkId);
        taskMap.put("upTs", upTs);
        this.updateTask(taskMap);
    }

    /**
     * @Method: upTaskToHandSuccess
     * @Param: [jobCode, bizDate]
     * @Return: void
     * @Description： 更新任务到置虚
     * @Author： jd.chen
     * @Date： 2021/6/21 20:07
     * @Version： V1.0
     */
    public void upTaskToHandSuccess(String pkId, String upTs) {
        Map taskMap = new HashMap(16);
        taskMap.put("taskStatus", Const.TASK_HAND_SUCCESS);
        taskMap.put("execStTs", upTs);
        taskMap.put("execEndTs", upTs);
        taskMap.put("pkId", pkId);
        taskMap.put("upTs", HdrsDateUtil.getCurTs());
        this.updateTask(taskMap);
    }

    /**
     * @Method: upTaskToStop <br>
     * @Param: [pkId, upTs] <br>
     * @Return: void <br>
     * @Description：更新任务到暂停<br>
     * @Author： gc.zuo<br>
     * @Date： 2022/1/26 14:43 <br>
     * @Version： V1.0<br>
     */
    public void upTaskToStop(String pkId, String upTs) {
        Map taskMap = new HashMap(16);
        taskMap.put("taskStatus", Const.TASK_STOP);
        taskMap.put("pkId", pkId);
        taskMap.put("upTs", upTs);
        this.updateTask(taskMap);
    }

    /**
     * 定时器更新失败任务
     *
     * @param map
     */
    public void updateFailTask(Map map) {
        this.periodTaskDao.updateFailTask(map);
    }

    /**
     * @Method: batchUpdateTask
     * @Param: [taskCodeList, bizDate]
     * @Return: void
     * @Description： 批量修改任务状态为待处理
     * @Author： jd.chen
     * @Date： 2021/6/21 23:30
     * @Version： V1.0
     */
    public void batchUpdateTask(List<String> taskCodeList, String bizDate) {
        log.info("批量修改任务状态为待处理,任务编码：{},业务日期:{}",taskCodeList.toString(),bizDate);
        if (CollectionUtils.isEmpty(taskCodeList) && StrUtil.isBlank(bizDate)) {
            throw new RuntimeException("批量修改任务状态为待处理失败，任务编码或业务日期为空");
        }
        Map paramMap = new HashMap(16);
        paramMap.put("taskCodeList", taskCodeList);
        paramMap.put("bizDate", bizDate);
        paramMap.put("taskStatus", Const.TASK_TODO_RUN);
        paramMap.put("execStTsIsNull", true);
        paramMap.put("execEndTsIsNull", true);
        paramMap.put("upTs", HdrsDateUtil.getCurTs());
        this.updateTask(paramMap);
    }

    /**
     * @Method: batchUpdateTaskStatus
     * @Param: [periodTaskVo]
     * @Return: void
     * @Description： 批量修改任务状态
     * @Author： jd.chen
     * @Date： 2021/6/21 11:41
     * @Version： V1.0
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int batchUpdateTaskStatus(PeriodTaskVo periodTaskVo) {
        log.debug("【PeriodTaskService.batchUpdateTaskStatus】periodTaskVo: {}", periodTaskVo);
        int successCount = 0;
        if (CollectionUtils.isNotEmpty(periodTaskVo.getPeriodTaskList())) {
            for (PeriodTask periodTask : periodTaskVo.getPeriodTaskList()) {
                if (updateTaskStatusInBatch(periodTask, periodTaskVo.getTaskStatus())) {
                    successCount++;
                }
            }
        }
        return successCount;
    }

    /**
     * @Method: updateTaskStatusInBatch
     * @Param: [periodTask, editTaskStatus]
     * @Return: boolean
     * @Description： 更新作业，批量中的一个
     * @Author： jd.chen
     * @Date： 2021/6/24 14:51
     * @Version： V1.0
     */
    public boolean updateTaskStatusInBatch(PeriodTask periodTask, String editTaskStatus) {
        try {
            updateTaskStatus(editTaskStatus, periodTask);
            return true;
        } catch (BizException e) {
            log.error("【updateTaskStatusInBatch】异常：{}", e.getErrMsg(), e);
            return false;
        } catch (Exception e) {
            log.error("【updateTaskStatusInBatch】异常：{}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * @Method: updateTaskStatus
     * @Param: [editTaskStatus, periodTask]
     * @Return: void
     * @Description： 更新任务状态
     * @Author： jd.chen
     * @Date： 2021/6/21 19:15
     * @Version： V1.0
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void updateTaskStatus(String editTaskStatus, PeriodTask periodTask) {
        if (editTaskStatus.equals(periodTask.getTaskStatus())) {
            log.info("修改的状态与原任务状态相同，无需修改。taskCode:{},bizDate:{}", periodTask.getTaskCode(), periodTask.getBizDate());
            throw new BizException(ErrorCode.ERROR_852001);
        }
        switch (editTaskStatus) {
            //待处理
            case Const.TASK_TODO_RUN:
                this.upStatusToToDo(periodTask);
                break;
            //置虚
            case Const.TASK_HAND_SUCCESS:
                this.upStatusToHandSuccess(periodTask);
                break;
            //暂停
            case Const.TASK_STOP:
                this.upStatusToStop(periodTask);
                break;
            default:
                log.warn("界面修改任务状态异常，修改的任务状态为：{}，taskCode:{},bizDate:{}", editTaskStatus, periodTask.getTaskCode(), periodTask.getBizDate());
                throw new BizException(ErrorCode.ERROR_851001);
        }
    }

    /**
     * @Method: upStatusToToDo
     * @Param: [periodTask]
     * @Return: void
     * @Description： 更新任务状态到待处理
     * @Author： jd.chen
     * @Date： 2021/6/21 19:40
     * @Version： V1.0
     */
    private void upStatusToToDo(PeriodTask periodTask) {
        log.info("更新任务状态到待处理,任务编码：{},业务日期:{}",periodTask.getTaskCode(),periodTask.getBizDate());
        switch (periodTask.getTaskStatus()) {
            case Const.TASK_SUCCESS:
            case Const.TASK_HAND_SUCCESS:
                this.upSuccToToDo(periodTask);
                break;
            case Const.TASK_FAIL:
            case Const.TASK_STOP:
                this.upFailToToDo(periodTask);
                break;
            default:
                log.warn("任务状态处理中，不允许修改，taskStatus:{},taskCode:{},bizDate:{}",
                        periodTask.getTaskStatus(), periodTask.getTaskCode(), periodTask.getBizDate());
                throw new BizException(ErrorCode.ERROR_851002);
        }
    }

    /**
     * @Method: upSuccToToDo
     * @Param: [periodTask]
     * @Return: void
     * @Description： 任务状态成功更新为待处理
     * @Author： jd.chen
     * @Date： 2021/6/21 19:40
     * @Version： V1.0
     */
    private void upSuccToToDo(PeriodTask periodTask) {
        log.info("任务状态成功更新为待处理,任务编码：{},业务日期：{}",periodTask.getTaskCode(),periodTask.getBizDate());
        PeriodJob job = getJobAfterTaskToDo(periodTask, HdrsDateUtil.getCurTs());
        this.periodJobService.upJobToToDo(job.getJobCode(), job.getBizDate(), HdrsDateUtil.getCurTs());

    }

    /**
     * @Method: upFailToToDo
     * @Param: [periodTask]
     * @Return: void
     * @Description： 任务状态失败更新为待处理
     * @Author： jd.chen
     * @Date： 2021/6/21 19:41
     * @Version： V1.0
     */
    private void upFailToToDo(PeriodTask periodTask) {
        log.info("任务状态失败更新为待处理,任务编码：{},业务日期:{}",periodTask.getTaskCode(),periodTask.getBizDate());
        String curTs = HdrsDateUtil.getCurTs();

        // 1.2.3. 更新任务状态，并获取作业信息
        PeriodJob job = getJobAfterTaskToDo(periodTask, curTs);
        // 4. 原作业未完成 不处理
        this.periodJobService.upJobToToDo(job.getJobCode(), job.getBizDate(), curTs);
    }

    /**
     * @Method: getJobAfterTaskToDo
     * @Param: [periodTask, curTs]
     * @Return: com.hex.ds.hdrs.period.job.po.PeriodJob
     * @Description： 更新任务状态，并获取作业信息
     * @Author： jd.chen
     * @Date： 2021/7/9 11:20
     * @Version： V1.0
     */
    private PeriodJob getJobAfterTaskToDo(PeriodTask periodTask, String curTs) {
        log.info("更新任务状态，并获取作业信息,任务编码：{},业务日期：{}",periodTask.getTaskCode(),periodTask.getBizDate());
        // 1. 任务状态修改为待处理
        this.upTaskToDo(periodTask.getPkId(), curTs);
        // TODO 如果该任务所属的作业下有多个任务，比如三个任务TASK1、TASK2、TASK3，TASK1为已完成或置虚状态，TASK2任务正在处理，这个时候修改内存信息是否合理
        // 2. 修改内存
        handService.upTaskToDo(periodTask.getJobCode(), periodTask.getBizDate(), periodTask.getTaskCode(), curTs);
        // 3. 获取作业信息
        return periodJobService.queryByJobCodeAndBizDate(periodTask.getJobCode(), periodTask.getBizDate());
    }

    /**
     * @Method: upStatusToHandSuccess
     * @Param: [editTaskStatus, periodTask]
     * @Return: void
     * @Description： 更新任务状态为置虚
     * @Author： jd.chen
     * @Date： 2021/6/21 19:41
     * @Version： V1.0
     */
    private void upStatusToHandSuccess(PeriodTask periodTask) {
        log.info("更新任务状态为置虚,任务编码：{}，业务日期：{}",periodTask.getTaskCode(),periodTask.getBizDate());
        String taskStatus = periodTask.getTaskStatus();
        //待处理 失败 暂停可以修改为置虚
        switch (taskStatus) {
            case Const.TASK_TODO_RUN:
            case Const.TASK_FAIL:
            case Const.TASK_STOP:
                this.toHandSuccess(periodTask);
                break;
            default:
                log.warn("任务状态处理中|处理完成，不允许修改为置虚，taskStatus:{},taskCode:{},bizDate:{}",
                        taskStatus, periodTask.getTaskCode(), periodTask.getBizDate());
                throw new BizException(ErrorCode.ERROR_851003);
        }
    }

    /**
     * @Method: upStatusToStop <br>
     * @Param: [periodTask] <br>
     * @Return: void <br>
     * @Description：更新任务状态为暂停<br>
     * @Author： gc.zuo<br>
     * @Date： 2022/1/26 13:46 <br>
     * @Version： V1.0<br>
     */
    private void upStatusToStop(PeriodTask periodTask) {
        log.info("更新任务状态为暂停,任务编码：{},业务日期:{}",periodTask.getTaskCode(),periodTask.getBizDate());
        String taskStatus = periodTask.getTaskStatus();
        // TODO 逻辑不正确，正确情况下只有待处理状态得任务才可以暂停
        switch (taskStatus) {
            case Const.TASK_RUNNING:
                log.warn("任务状态处理中，不允许修改为暂停，taskStatus:{},taskCode:{},bizDate:{}",
                        taskStatus, periodTask.getTaskCode(), periodTask.getBizDate());
                throw new BizException(ErrorCode.ERROR_851003);
            default:
                this.statusToStop(periodTask);
                break;
        }
    }

    /**
     * @Method: statusToStop <br>
     * @Param: [periodTask] <br>
     * @Return: void <br>
     * @Description：更新任务状态为暂停<br>
     * @Author： gc.zuo<br>
     * @Date： 2022/1/26 15:10 <br>
     * @Version： V1.0<br>
     */
    private void statusToStop(PeriodTask periodTask) {
        String taskCode = periodTask.getTaskCode();
        String bizDate = periodTask.getBizDate();
        String jobCode = periodTask.getJobCode();
        String pkId = periodTask.getPkId();
        String curTs = HdrsDateUtil.getCurTs();

        // 1. 修改内存
        this.handService.upTaskToStop(jobCode, bizDate, taskCode, curTs);
        // 2. 任务状态修改为暂停
        this.upTaskToStop(pkId, curTs);
        // 3. 更新原作业状态
        PeriodJob job = periodJobService.queryByJobCodeAndBizDate(jobCode, bizDate);
        if (Const.JOB_DO_SUCCESS.equals(job.getJobStatus())) {
            //如果作业完成了  更新为未完成
            this.periodJobService.upJobToToDo(job.getJobCode(), job.getBizDate(), curTs);
        }
    }

    /**
     * @Method: toHandSuccess
     * @Param: [periodTask]
     * @Return: void
     * @Description： 任务更新为置虚
     * @Author： jd.chen
     * @Date： 2021/6/21 19:52
     * @Version： V1.0
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void toHandSuccess(PeriodTask periodTask) {
        String taskCode = periodTask.getTaskCode();
        String bizDate = periodTask.getBizDate();
        String jobCode = periodTask.getJobCode();
        String pkId = periodTask.getPkId();
        String curTs = HdrsDateUtil.getCurTs();
        try {
            log.info("任务更新为置虚,任务编码：{},业务日期:{}",periodTask.getTaskCode(),periodTask.getBizDate());
            // 1. 任务状态修改为置虚
            this.upTaskToHandSuccess(pkId, curTs);
            // 2. 修改内存
            this.handService.upToDoTaskToHandSucc(jobCode, bizDate, taskCode, curTs);
            //删除可执行队列(文件扫描任务)
            toRunManager.getSortQueue(periodTask.getAppCode()).removeTask(periodTask);
            //去除待执行队列中的任务
            this.handService.removeToDoTask(jobCode, bizDate);
            //2. 更新内存中任务最新完成时间队列 2024年7月29日15:10:23 最新完成队列已暂时废弃
            //lstFinishManager.updateLstTask(periodTask);
            // 3. 原作业状态
            PeriodJob job = periodJobService.queryByJobCodeAndBizDate(jobCode, bizDate);
            // 作业下任务都完成或置虚，作业修改为处理完成
            int unFinishTaskCount = this.unFinishTaskCountInJob(jobCode, bizDate, taskCode);
            if (unFinishTaskCount == 0) {
                this.periodJobService.upJobToSuccess(job.getPkId(), job.getJobStTs(), curTs);
            } else {
                //置虚后触发作业的下个任务
                this.handService.touchNextTask(jobCode, bizDate, taskCode);
            }
        } catch (Exception e) {
            log.error("修改置虚出现异常{}", e.getMessage(), e);
            throw new BizException(ErrorCode.ERROR_851004);
        }

    }

    /**
     * @Method: unFinishTaskCountInJob
     * @Param: [jobCode, bizDate, taskCode]
     * @Return: int
     * @Description： 作业中未完成（除了处理成功|置虚）的任务数（不包含本任务）
     * @Author： jd.chen
     * @Date： 2021/6/21 19:55
     * @Version： V1.0
     */
    public int unFinishTaskCountInJob(String jobCode, String bizDate, String taskCode) {
        Map qryMap = new HashMap(16);
        qryMap.put("jobCode", jobCode);
        qryMap.put("bizDate", bizDate);
        List<PeriodTask> taskList = qryPeriodTaskList(qryMap);
        int unFinishTaskCount = 0;
        for (PeriodTask task : taskList) {
            if (!StrUtil.equalsAnyIgnoreCase(task.getTaskStatus(),Const.TASK_SUCCESS)
                    && !StrUtil.equalsAnyIgnoreCase(task.getTaskStatus(),Const.TASK_HAND_SUCCESS)) {
                unFinishTaskCount += 1;
            }
        }
        return unFinishTaskCount;
    }


    public List<PeriodTask> qryTaskByTaskCodes(String appCode, String bizDate, List<String> taskCodeList) {
        log.debug("查询Task List【PeriodTaskService.qryTaskList】====》");
        Map map = new HashMap(16);
        map.put("appCode", appCode);
        map.put("bizDate", bizDate);
        map.put("taskCodeList", taskCodeList);
        return this.qryPeriodTaskList(map);
    }

    public List<PeriodTask> qryPeriodTaskList(String appCode, List<String> taskCodeList) {
        String startTime = HdrsDateUtil.getAheadTime("0", 2, HdrsDateUtil.getCurrentTime());
        String endTime = HdrsDateUtil.getAheadTime("0", 1, HdrsDateUtil.getCurrentTime());
        Map map = new HashMap(16);
        map.put("appCode", appCode);
        map.put("taskCodeList", taskCodeList);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return this.qryPeriodTaskList(map);
    }

    /**
     * 查询周期任务实例List 可在该方法上扩展
     * 注意：不可修改返回值信息，需要添加条件可以在mapper里直接添加
     *
     * @param map
     * @return
     */
    public List<PeriodTask> qryPeriodTaskList(Map map) {
        return this.periodTaskDao.qryTaskInfoList(map);
    }

    /**
     * 删除 task 信息
     *
     * @param pkIds
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deltasksinfo(List<String> pkIds) {
        log.debug("【PeriodTaskService.deltasksinfo】pkIds: {}", pkIds);
        this.periodTaskDao.deltaskinfo(pkIds);
    }

    /**
     * @param taskCode
     * @param bizDate
     * @return
     */
    public PeriodTask qryPeriodTaskInfo(String taskCode, String bizDate) {
        Map paramMap = new HashMap(16);
        paramMap.put("taskCode", taskCode);
        paramMap.put("bizDate", bizDate);
        return this.periodTaskDao.qryPeriodTaskInfo(paramMap);
    }

    /**
     * 下载 task 信息
     *
     * @param periodTasks
     * @param response
     */
    public void downloadTaskInfo(List<PeriodTask> periodTasks, HttpServletResponse response) {
        log.debug("【PeriodJobService.downloadTaskInfo】periodTasks: {}", periodTasks);
        List<Map<String, Object>> timeTaskExecList = new ArrayList<Map<String, Object>>();
        for (PeriodTask pt : periodTasks) {
            Map<String, Object> map = new LinkedHashMap<>(16);
            map.put("作业编码", pt.getJobCode());
            map.put("任务编码", pt.getTaskCode());
            map.put("任务名称", pt.getTaskName());
            map.put("业务日期", pt.getBizDate());
            map.put("执行文件", pt.getShellPath());
            map.put("依赖作业", pt.getDependJob());
            map.put("依赖任务", pt.getDependTask());
            map.put("出错次数", pt.getErrCount());
            map.put("创建任务时间", pt.getCrtTs());
            map.put("更新时间", pt.getUpTs());
            map.put("互斥作业", pt.getMutexJob());
            map.put("互斥任务", pt.getMutexTask());
            map.put("批次标签", pt.getBatchTag());
            map.put("允许出错次数", pt.getAllowErrCount());
            map.put("资源数", pt.getResNum());
            map.put("优先级", pt.getPriorityLevel());
            map.put("应用编码", pt.getAppCode());
            map.put("执行节点编码", pt.getAgentCode());
            map.put("指定节点编码", pt.getAppointAgentCode());
            map.put("预计执行时长", pt.getPlanExecDuration());
            map.put("超时时长", pt.getOverPlanDuration());
            map.put("出错间隔时间", pt.getErrDifferDuration());
            map.put("执行开始时间", pt.getExecStTs());
            map.put("执行完成时间", pt.getExecEndTs());
            map.put("任务状态", DownPeriodJobExcelHelper.getTaskStatus(pt.getTaskStatus()));
            //map.put("当前执行日志", pt.getTaskExecLog());
            timeTaskExecList.add(map);
        }
        try {
            FileUtil.downloadExcel(timeTaskExecList, response);
        } catch (IOException e) {
            log.error("导出任务定义表出错{}", e.getMessage(),e);
        }
    }

    public void upTaskStatus(PeriodTaskVo periodTaskVo) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("pkIds", periodTaskVo.getPkIds());
        map.put("taskStatus", periodTaskVo.getTaskStatus());
        map.put("upTs", HdrsDateUtil.getCurTs());
        this.updateTask(map);
    }

    /**
     * 获取当前用户一段时间内的执行情况
     *
     * @param username
     * @param startTime
     * @return
     */
    public List getTaskListByCruuentUser(String username, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentUser】username: {}", username);
        Map map = new HashMap(16);
        map.put("username", username);
        map.put("startTime", startTime);
        return this.periodTaskDao.getTaskListByCruuentUser(map);
    }

    /**
     * 获取当前用户一段时间内的执行情况
     *
     * @param appCode
     * @param startTime
     * @return
     */
    public List getTaskListByCruuentApp(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap(16);
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.periodTaskDao.getTaskListByCruuentApp(map);
    }

    public List getTaskListByCruuentApp2(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap(16);
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.periodTaskDao.getTaskListByCruuentApp2(map);
    }

    public List getTaskListByCruuentApp3(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap(16);
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.periodTaskDao.getTaskListByCruuentApp3(map);
    }

    public List<PeriodTask> qryTaskCodesByAppCode(PeriodTaskDto periodTaskDto) {
        log.debug("【PeriodTaskService.qryTaskCodesByAppCode】periodTaskDto: {}", periodTaskDto);
        List appCodes = (periodTaskDto.getAppCodes() != null) ? Arrays.asList(periodTaskDto.getAppCodes()) : new ArrayList();
        if (CollectionUtils.isEmpty(appCodes)) {
            appCodes.add(periodTaskDto.getAppCode());
        }
        Map map = new HashMap(16);
        map.put("list", appCodes);
        map.put("isOrder", periodTaskDto.getIsOrder());
        map.put("taskCode", periodTaskDto.getTaskCode());
        map.put("taskStatus", periodTaskDto.getTaskStatus());
        return this.periodTaskDao.qryTaskCodesByAppCode(map);
    }

    public Integer countTask(Map paramMap) {
        return this.periodTaskDao.countTask(paramMap);
    }

    public Integer countUnAppointTask(Map<String,String> paramMap){
        return this.periodTaskDao.countUnAppointTask(paramMap);
    }

    public Integer countTask(String taskStatus) {
        return this.countTask(null, null, taskStatus);
    }

    public Integer countTask(String appCode, String taskStatus) {
        return this.countTask(appCode, null, taskStatus);
    }

    public Integer countTask(String appCode, String bizDate, String taskStatus) {
        Map paramMap = new HashMap(16);
        paramMap.put("taskStatus", taskStatus);
        paramMap.put("appCode", appCode);
        paramMap.put("bizDate", bizDate);
        return this.countTask(paramMap);
    }

    /**
     * Echars图信息查询
     *
     * @param jobCode
     * @return
     */
    public List<PeriodTask> qryPeriodTaskInfoByEchars(String jobCode) {
        log.debug("【PeriodTaskService.qryPeriodTaskInfoByEchars】jobCode: {}", jobCode);
        Map paramMap = new HashMap(16);
        paramMap.put("jobCode", jobCode);
        return this.periodTaskDao.qryTaskInfoList(paramMap);
    }

    /**
     * 查询Echars图表的Task信息
     *
     * @param periodTaskDto
     * @return
     */
    public List<List<String>> qryTaskInfoByEchars(PeriodTaskDto periodTaskDto) {
        log.debug("【PeriodTaskService.qryTaskInfoByEchars】taskCode: {}", periodTaskDto.getTaskCode());
        List<List<String>> resList = new ArrayList<>();
        List<PeriodTaskByEcharsVo> list = this.periodTaskDao.qryTaskInfoByEchars(periodTaskDto);
        if (list != null && list.size() > 0) {
            for (PeriodTaskByEcharsVo vo : list) {
                List ll = new ArrayList();
                vo.setBizDate(HdrsDateUtil.getNormalDate(vo.getBizDate()));
                ll.add(vo.getBizDate());
                ll.add(HdrsDateUtil.calLastedTime((vo.getExecStTs()), vo.getExecEndTs()));
                ll.add(vo.getTaskCode());
                ll.add(vo.getTaskName());
                ll.add(vo.getTaskStatus());
                ll.add(vo.getExecStTs());
                ll.add(vo.getExecEndTs());
                resList.add(ll);
            }
        }
        return resList;
    }

    /**
     * 查询Echars图表下方的表格信息
     *
     * @param periodTaskDto
     * @return
     */
    public List<PeriodTaskByEcharsVo> qryTaskInfoByTables(PeriodTaskDto periodTaskDto) {
        log.debug("【PeriodTaskService.qryTaskInfoByTables】taskCode: {}", periodTaskDto.getTaskCode());
        List<PeriodTaskByEcharsVo> resList = this.periodTaskDao.qryTaskInfoByEchars(periodTaskDto);
        if (CollectionUtils.isNotEmpty(resList)) {
            for (PeriodTaskByEcharsVo echarsVo : resList) {
                if (StringUtils.isNotBlank(echarsVo.getExecStTs()) && StringUtils.isNotBlank(echarsVo.getExecEndTs())) {
                    echarsVo.setCostTs(SecToTimeUtil.getCostTs(echarsVo.getExecStTs(), echarsVo.getExecEndTs()));
                }
            }
        }
        return resList;
    }

    public List<Map> countByStatus(Map paramMap) {
        return this.periodTaskDao.countByStatus(paramMap);
    }

    public List<Map> getStatusCountByAppCode(String appCode) {
        Map paramMap = new HashMap(16);
        paramMap.put("appCode", appCode);
        return this.countByStatus(paramMap);
    }

    public List<Map> getStatusCount(String appCode, String bizDate) {
        Map paramMap = new HashMap(16);
        paramMap.put("appCode", appCode);
        if (StringUtils.isNotBlank(bizDate)) {
            paramMap.put("bizDate", bizDate);
        }
        return this.countByStatus(paramMap);
    }

    /**
     * 查询任务状态
     *
     * @param periodTask
     */
    public String selectTaskStatus(PeriodTask periodTask) {
        Map paramMap = new HashMap(16);
        paramMap.put("taskCode", periodTask.getTaskCode());
        paramMap.put("bizDate", periodTask.getBizDate());
        List<PeriodTask> taskList = this.periodTaskDao.qryTaskStatus(paramMap);
        return taskList.get(0).getTaskStatus();
    }

    public void deleteTaskByJob(String jobCode, String bizDate) {
        Map paramMap = new HashMap(16);
        paramMap.put("jobCode", jobCode);
        paramMap.put("bizDate", bizDate);
        periodTaskDao.deleteTaskByJob(paramMap);

    }

    /**
     * @Method: delTaskByDate <br>
     * @Param: [map] <br>
     * @Return: void <br>
     * @Description：根据日期删除周期任务实例数据<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/3 16:27 <br>
     * @Version： V1.0<br>
     */
    public void delTaskByDate(Map map) {
        periodTaskDao.delTaskByDate(map);
    }

    /**
     * @Method: reductionTask <br>
     * @Param: [bitchId] <br>
     * @Return: void <br>
     * @Description：还原周期任务实例数据<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/3 16:27 <br>
     * @Version： V1.0<br>
     */
    public void reductionTask(String bitchId) {
        periodTaskDao.reductionTask(bitchId);
    }

    private String setDateTimeSeparator(String dateTime) {
        String result = "";
        if (StringUtils.isNotBlank(dateTime) && dateTime.length() == 18) {
            StringBuilder builder = new StringBuilder();
            builder.append(dateTime.substring(0, 10)).append(" ").append(dateTime.substring(10, 18));
            result = builder.toString();
        }
        return result;
    }

    /**
     * @Method: selectUnionCountByTaskStatus
     * @Param: [paramMap]
     * @Return: java.util.List<java.util.Map>
     * @Description: 查询所有状态的周期任务实例数量
     * @Author: ji.tang
     * @Date: 2022/6/16 16:03
     * @Version: V1.0
     */
    public List<Map> selectUnionCountByTaskStatus(Map paramMap) {
        return this.periodTaskDao.selectUnionCountByTaskStatus(paramMap);
    }

    /**
     * @Method: batchUpdateTaskBizDate
     * @Param: [periodTaskList]
     * @Return: void
     * @Description: 修改周期任务业务日期
     * @Author: ji.tang
     * @Date: 2022/7/15 16:59
     * @Version: V1.0
     */
    public void batchUpdateTaskBizDate(List<PeriodTask> periodTaskList, String bizDate) {
        if (CollectionUtils.isNotEmpty(periodTaskList)) {
            StringBuilder sb = new StringBuilder();
            for (PeriodTask task : periodTaskList) {
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(task.getTaskCode());
                task.setBizDate(bizDate);
                Map map = MapUtil.Entity2Map(task);
                this.periodTaskDao.updateBizDateByMap(map);
            }
            log.info("修改周期任务业务日期,任务编码：{}",sb);
        }
    }


    public List<PeriodTask> queryTaskStatusCount(String jobCode, String bizDate) {
        PeriodTask periodTask = new PeriodTask().setJobCode(jobCode).setBizDate(bizDate);
        return periodTaskDao.queryTaskStatusCount(periodTask);
    }

    /*
     * @Method: sortByDependTask <br>
     * @Param: [periodTasks] <br>
     * @Return: java.util.List<java.lang.String> <br>
     * @Description：根据任务依赖进行排序<br>
     * @Author： wz.li<br>
     * @Date： 2023/7/21 13:51 <br>
     * @Version： V2.0.2<br>
     */
    public List<String> sortByDependTask(List<PeriodTask> periodTasks) {
        List<String> periodTaskCodeList = periodTasks.stream().map(PeriodTask::getTaskCode).collect(Collectors.toList());
        // 将ArrayList转换为Map,key为id,value为pid和该对象本身组成的List
        Map<String, List<PeriodTask>> periodTaskMap = buildPeriodTaskMap(periodTaskCodeList, periodTasks);
        // 根据pid的依赖进行拓扑排序
        Stack<PeriodTask> stack = stacekSort(periodTaskMap, periodTaskCodeList);
        // 输出排序后的结果
        List<String> sortList = new ArrayList<>();
        while (!stack.isEmpty()) {
            sortList.add(0, stack.pop().getTaskCode());
        }
        return sortList;
    }

    private Map<String, List<PeriodTask>> buildPeriodTaskMap(List<String> periodTaskCodeList, List<PeriodTask> periodTasks) {
        Map<String, List<PeriodTask>> objectMap = new HashMap<>();
        for (PeriodTask periodTask : periodTasks) {
            List<String> dependTaskCodeList = ListUtils.intersection(Arrays.asList(StrUtil.split(periodTask.getDependTask(), ",")), periodTaskCodeList);
            List<PeriodTask> tempList = new ArrayList<>();
            tempList.add(periodTask);
            for (String dependTaskCode : dependTaskCodeList) {
                tempList.addAll(objectMap.getOrDefault(dependTaskCode, new ArrayList<>()));
            }
            objectMap.put(periodTask.getTaskCode(), tempList);
        }
        return objectMap;
    }

    private Stack<PeriodTask> stacekSort(Map<String, List<PeriodTask>> periodTaskMap, List<String> periodTaskCodeList) {
        Stack<PeriodTask> stack = new Stack<>();
        Map<String, Boolean> visited = new HashMap<>();
        for (String taskCode : periodTaskMap.keySet()) {
            if (!visited.containsKey(taskCode)) {
                dfs(taskCode, periodTaskMap, visited, stack, periodTaskCodeList);
            }
        }
        return stack;
    }

    private void dfs(String id, Map<String, List<PeriodTask>> objectMap, Map<String,
            Boolean> visited, Stack<PeriodTask> stack, List<String> periodTaskCodeList) {
        if (visited.containsKey(id)) {
            return;
        } else {
            visited.put(id, true);
            List<String> dependTaskCodeList = org.apache.commons.collections4.ListUtils.intersection(Arrays.asList(StrUtil.split(objectMap.get(id).get(0).getDependTask(), ",")), periodTaskCodeList);
            for (String childId : dependTaskCodeList) {
                dfs(childId, objectMap, visited, stack, periodTaskCodeList);
            }
            stack.push(objectMap.get(id).get(0));
        }
    }

    /*
     * @Method: getDependPeriodTaskDto <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto <br>
     * @Description：根据任务编码和业务日期查询对应的任务实例或定义<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:07 <br>
     * @Version： V2.0.2<br>
     */
    private DependPeriodTaskDto getDependPeriodTaskDto(String taskCode, String bizDate) {
        PeriodTask periodTask = qryPeriodTaskInfo(taskCode, bizDate);
        if (periodTask != null) {
            return dependPeriodTaskDtoConverter.toNodeInfo(periodTask);
        }
        PeriodTaskDef periodTaskDef = periodTaskDefService.qryPeriodTaskDef(taskCode);
        if (periodTaskDef == null) {
            throw new RuntimeException("上游依赖任务定义【" + taskCode + "】不存在");
        }
        return dependPeriodTaskDtoConverter.toNodeInfoByDef(periodTaskDef);
    }

    /*
     * @Method: getLastTaskForJob <br>
     * @Param: [jobCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto <br>
     * @Description：根据作业编码和业务日期该作业最后一个任务实例或任务定义<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:08 <br>
     * @Version： V2.0.2<br>
     */
    private DependPeriodTaskDto getLastTaskForJob(String jobCode, String bizDate) {
        List<PeriodTask> periodTaskList = qryTaskListInJob(jobCode, bizDate);
        if (CollectionUtil.isNotEmpty(periodTaskList)) {
            return getLastPeriodTaskForJob(periodTaskList);
        }
        List<PeriodTaskDef> periodTaskDefList = periodTaskDefService.getTaskDefsByJobCode(jobCode);
        return getLastPeriodTaskDefForJob(periodTaskDefList, jobCode);
    }

    /*
     * @Method: getLastPeriodTaskForJob <br>
     * @Param: [periodTaskList] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto <br>
     * @Description：获取指定任务实例集合中最后一个任务实例对象<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:08 <br>
     * @Version： V2.0.2<br>
     */
    private DependPeriodTaskDto getLastPeriodTaskForJob(List<PeriodTask> periodTaskList) {
        List<String> sortByTaskCodeList = sortByDependTask(periodTaskList);
        PeriodTask dependTask = periodTaskList.stream()
                .filter(o -> o.getTaskCode().equals(sortByTaskCodeList.get(sortByTaskCodeList.size() - 1))).collect(Collectors.toList()).get(0);
        return dependPeriodTaskDtoConverter.toNodeInfo(dependTask);
    }

    /*
     * @Method: getLastPeriodTaskDefForJob <br>
     * @Param: [periodTaskDefList] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto <br>
     * @Description：获取指定任务定义集合中最后一个任务定义<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:09 <br>
     * @Version： V2.0.2<br>
     */
    private DependPeriodTaskDto getLastPeriodTaskDefForJob(List<PeriodTaskDef> periodTaskDefList, String jobCode) {
        if (CollectionUtil.isEmpty(periodTaskDefList)) {
            throw new RuntimeException("上游依赖作业定义【" + jobCode + "】已不存在或没有任务定义");
        }
        List<String> sortByTaskCodeList = periodTaskDefService.sortByDependTask(periodTaskDefList);
        PeriodTaskDef periodTaskDef = periodTaskDefList.stream()
                .filter(o -> o.getTaskCode().equals(sortByTaskCodeList.get(sortByTaskCodeList.size() - 1))).collect(Collectors.toList()).get(0);
        return dependPeriodTaskDtoConverter.toNodeInfoByDef(periodTaskDef);
    }

    /*
     * @Method: upDependChat <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.TaskAllDependDto <br>
     * @Description：获取指定任务编码和业务日期的上游依赖图数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:10 <br>
     * @Version： V2.0.2<br>
     */
    public TaskAllDependDto upDependChat(String taskCode, String bizDate, String showType) {

        DependPeriodTaskDto crunTask = getDependPeriodTaskDto(taskCode, bizDate);
        TaskAllDependDto taskAllDependDto = new TaskAllDependDto(crunTask.getNodeName());
        buildUpDependChatData(showType, crunTask, crunTask, bizDate, taskAllDependDto);
        return taskAllDependDto;
    }

    public TaskDependDto upDepend(String taskCode, String bizDate) {
        //任务编码
        PeriodTaskDef periodTaskDef = periodTaskDefService.qryPeriodTaskDef(taskCode);
        Map map = new HashMap(16);
        map.put("taskCode", taskCode);
        map.put("bizDate", bizDate);
        List<PeriodTask> taskList = qryPeriodTaskList(map);
        TaskDependDto taskDependDto = new TaskDependDto();
        if(CollectionUtil.isNotEmpty(taskList)){
            taskDependDto.setId(taskList.get(0).getPkId()).setTaskCode(taskCode);
            taskDependDto.setStatus(taskList.get(0).getTaskStatus());
            taskDependDto.setPeriodTask(taskList.get(0));
        }
        buildUpDependData(periodTaskDef,taskDependDto,bizDate);
        return taskDependDto;
    }

    public TaskDependDto downDepend(String taskCode, String bizDate) {
        PeriodTaskDef periodTaskDef = periodTaskDefService.qryPeriodTaskDef(taskCode);
        Map map = new HashMap(16);
        map.put("taskCode", taskCode);
        map.put("bizDate", bizDate);
        List<PeriodTask> taskList = qryPeriodTaskList(map);
        TaskDependDto taskDependDto = new TaskDependDto();
        if(CollectionUtil.isNotEmpty(taskList)){
            taskDependDto.setId(taskList.get(0).getPkId()).setTaskCode(taskCode);
            taskDependDto.setStatus(taskList.get(0).getTaskStatus());
            taskDependDto.setPeriodTask(taskList.get(0));
        }
        buildDownDependData(periodTaskDef, taskDependDto,bizDate);
        return taskDependDto;
    }

    private List<PeriodTaskDef> queryListByDependTask(String taskCode) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("dependTask", taskCode);
        return periodTaskDefDao.qryTaskDefList(paramMap);
    }

    private void buildDownDependData(PeriodTaskDef periodTaskDef, TaskDependDto taskDependDto, String bizDate) {
        DependNodesDataDto dependNodesDataDto = new DependNodesDataDto();
        //获取该节点的下游依赖
        List<PeriodTaskDef> periodTaskDefList = queryListByDependTask(periodTaskDef.getTaskCode());
        ArrayList<Object> nextDep = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(periodTaskDefList)){
            for (PeriodTaskDef taskDef : periodTaskDefList) {
                Map map = new HashMap(16);
                map.put("taskCode", taskDef.getTaskCode());
                map.put("bizDate", bizDate);
                List<PeriodTask> taskList = qryPeriodTaskList(map);
                if(CollectionUtil.isNotEmpty(taskList)){
                    TaskDependDto taskDependDto1 = new TaskDependDto(taskList.get(0).getPkId(),taskDef.getTaskCode());
                    taskDependDto1.setStatus(taskList.get(0).getTaskStatus());
                    taskDependDto1.setPeriodTask(taskList.get(0));
                    //1.将每一个下游依赖设置到nextDep里
                    nextDep.add(taskDependDto1);
                    //2.设置每一条边的信息
                    nextDep.add(new EdgeDataDto(taskList.get(0).getPkId(),taskDependDto.getId()));
                }
            }
        }
        List<PeriodTask> crunJobTaskList = qryTaskListInJob(periodTaskDef.getJobCode(), bizDate);
        List<String> sortTaskCodes = sortByDependTask(crunJobTaskList);
        if (sortTaskCodes.indexOf(periodTaskDef.getTaskCode()) == (crunJobTaskList.size() - 1)) {
            List<PeriodTask> downDependList = queryListByDependJob(periodTaskDef.getJobCode(), bizDate);
            if (periodTaskDefList.size() == 0 && downDependList.size() == 0){
                throw new RuntimeException("该任务不存在下游依赖");
            }
            for (PeriodTask downDependTask : downDependList) {
                TaskDependDto taskDependDto1 = new TaskDependDto(downDependTask.getPkId(),downDependTask.getTaskCode());
                taskDependDto1.setStatus(downDependTask.getTaskStatus());
                taskDependDto1.setPeriodTask(downDependTask);
                nextDep.add(taskDependDto1);
                //2.设置每一条边的信息
                nextDep.add(new EdgeDataDto(downDependTask.getPkId(),taskDependDto.getId()));
            }
        } else {
            if (periodTaskDefList.size() == 0){
                throw new RuntimeException("该任务不存在下游依赖");
            }
        }
        dependNodesDataDto.setNextDep(nextDep);
        taskDependDto.setData(dependNodesDataDto);
    }

    private void buildUpDependData(PeriodTaskDef periodTaskDef, TaskDependDto taskDependDto, String bizDate) {
        if (CollectionUtil.isEmpty(periodTaskDef.getDependTaskList()) && CollectionUtil.isEmpty(periodTaskDef.getDependJobList())) {
            throw new RuntimeException("该任务不存在上游依赖");
        }
        DependNodesDataDto dependNodesDataDto = new DependNodesDataDto();
        List<Object> lastDep = new ArrayList<>();
        //判断是否有上游任务节点
        if(!CollectionUtil.isEmpty(periodTaskDef.getDependTaskList())){
            for (String taskCode : periodTaskDef.getDependTaskList()) {
                Map map = new HashMap(16);
                map.put("taskCode",taskCode);
                map.put("bizDate", bizDate);
                //查询对应的taskCode是否有对应的实例生成
                List<PeriodTask> taskList = qryPeriodTaskList(map);
                if (CollUtil.isEmpty(taskList)){
                    throw new RuntimeException("上游依赖任务【"+ taskCode +"】,业务日期【"+bizDate+"】未生成实例");
                }
                if(CollectionUtil.isNotEmpty(taskList)){
                    TaskDependDto taskDependDto1 = new TaskDependDto(taskList.get(0).getPkId(),taskCode);
                    //设置状态
                    PeriodTask periodTask = taskList.get(0);
                    taskDependDto1.setStatus(periodTask.getTaskStatus());
                    taskDependDto1.setPeriodTask(periodTask);
                    //添加任务子节点信息
                    lastDep.add(taskDependDto1);
                    lastDep.add(new EdgeDataDto(taskDependDto.getId(), taskList.get(0).getPkId()));
                }
            }
        }
        //上游作业节点
        if(!CollectionUtil.isEmpty(periodTaskDef.getDependJobList())){
            for (String jobCode : periodTaskDef.getDependJobList()) {
                //判断是否有对应的作业实例生成
                PeriodJob upDependPeriodJob = periodJobService.queryByJobCodeAndBizDate(jobCode, bizDate);
                if(upDependPeriodJob != null){
                    DependNodesDataDto dependNodesDataDto1 = new DependNodesDataDto();
                    List<PeriodTaskDef> periodTaskDefList = periodTaskDefService.getTaskDefsByJobCode(jobCode);
                    if (CollectionUtil.isEmpty(periodTaskDefList)) {
                        throw new RuntimeException("上游依赖作业实例【" + jobCode + "】不存在或其下没有任务定义！");
                    }
                    //添加作业子节点
                    TaskDependDto taskDependDto1 = new TaskDependDto(upDependPeriodJob.getPkId(),jobCode);
                    //设置作业节点状态
                    PeriodJobDto periodJob = new PeriodJobDto().setJobCode(jobCode).setBizDate(bizDate);
                    taskDependDto1.setStatus(periodJobService.qryJobStatus(periodJob));
                    taskDependDto1.setShape("job");
                    ArrayList<TaskDependDto> children = new ArrayList<>();
                    for (PeriodTaskDef taskDef : periodTaskDefList) {
                        PeriodTask periodTask = qryPeriodTaskInfo(taskDef.getTaskCode(), bizDate);
                        TaskDependDto taskDependDtoChildren = new TaskDependDto(periodTask.getPkId(),periodTask.getTaskCode());
                        if(periodTask != null){
                            taskDependDtoChildren.setStatus(periodTask.getTaskStatus());
                            taskDependDtoChildren.setPeriodTask(periodTask);
                        }
                        taskDependDtoChildren.setJobCode(jobCode);
                        children.add(taskDependDtoChildren);
                    }
                    dependNodesDataDto1.setChildren(children);
                    taskDependDto1.setData(dependNodesDataDto1);
                    lastDep.add(taskDependDto1);
                    lastDep.add(new EdgeDataDto(taskDependDto.getId(),upDependPeriodJob.getPkId()));
                }
            }
        }
        dependNodesDataDto.setLastDep(lastDep);
        taskDependDto.setData(dependNodesDataDto);
    }

    /*
     * @Method: buildUpDependChatData <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建指定任务实例的上游依赖图数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:10 <br>
     * @Version： V2.0.2<br>
     */
    private void buildUpDependChatData(String showType, DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask, String bizDate,
                                       TaskAllDependDto taskAllDependDto) {
        if ("ALL_DEPEND".equals(showType) || isShowDepend(rootPeriodTask, crunTask)) {
            log.info("构建指定任务实例的上游依赖图数据，当前任务编码：{},业务日期:{}",crunTask.getTaskCode(),bizDate);
            buildTaskNode(crunTask, taskAllDependDto);
            buildDependJobLike(showType, rootPeriodTask, crunTask, bizDate, taskAllDependDto);
            buildDependTaskLike(showType, rootPeriodTask, crunTask, bizDate, taskAllDependDto);
        }
    }

    private boolean isShowDepend(DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask) {
        return rootPeriodTask.getTaskCode().equals(crunTask.getTaskCode())
                || rootPeriodTask.getDependJobList().contains(crunTask.getJobCode())
                || rootPeriodTask.getDependTaskList().contains(crunTask.getTaskCode());
    }

    /*
     * @Method: buildTaskNode <br>
     * @Param: [dependPeriodTaskDto, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建任务依赖图节点对象<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:10 <br>
     * @Version： V2.0.2<br>
     */
    private void buildTaskNode(DependPeriodTaskDto dependPeriodTaskDto, TaskAllDependDto taskAllDependDto) {
        DependNodesDto crunTaskNode = new DependNodesDto(dependPeriodTaskDto.getNodeName(), dependPeriodTaskDto.getNodeName(), false);
        if (!taskAllDependDto.getNodes().contains(crunTaskNode)) {
            taskAllDependDto.getNodes().add(crunTaskNode);
        }
    }

    /*
     * @Method: buildDependJobLike <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建任务依赖作业数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:11 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDependJobLike(String showType, DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        if (CollectionUtil.isNotEmpty(crunTask.getDependJobList())) {
            log.info("构建任务依赖作业数据,作业编码:{},业务日期：{}",crunTask.getDependJobList().toString(),bizDate);
            for (String jobCode : crunTask.getDependJobList()) {
                DependPeriodTaskDto dependPeriodTask = getLastTaskForJob(jobCode, bizDate);
                if (dependPeriodTask != null) {
                    buildNodeLike(showType, rootPeriodTask, crunTask, dependPeriodTask, bizDate, taskAllDependDto);
                }
            }
        }
    }

    /*
     * @Method: buildNodeLike <br>
     * @Param: [crunTask, dependTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建节点与节点之间连线<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:11 <br>
     * @Version： V2.0.2<br>
     */
    private void buildNodeLike(String showType, DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask, DependPeriodTaskDto dependTask,
                               String bizDate, TaskAllDependDto taskAllDependDto) {
        DependRelationDto dependRelationDto = new DependRelationDto(dependTask.getNodeName(), crunTask.getNodeName());
        if (!taskAllDependDto.getLinks().contains(dependRelationDto)) {
            taskAllDependDto.getLinks().add(dependRelationDto);
        }
        buildUpDependChatData(showType, rootPeriodTask, dependTask, bizDate, taskAllDependDto);
    }

    /*
     * @Method: buildDependTaskLike <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建指定节点上游任务依赖数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:11 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDependTaskLike(String showType, DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        if (CollectionUtil.isNotEmpty(crunTask.getDependTaskList())) {
            log.info("构建指定节点上游任务依赖数据,任务编码:{},业务日期:{}",crunTask.getTaskCode(),bizDate);
            for (String taskCode : crunTask.getDependTaskList()) {
                DependPeriodTaskDto dependTask = getDependPeriodTaskDto(taskCode, bizDate);
                buildNodeLike(showType, rootPeriodTask, crunTask, dependTask, bizDate, taskAllDependDto);
            }
        }
    }

    /*
     * @Method: upDependList <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.TaskAllDependListDto <br>
     * @Description：获取指定任务编码和业务日期的上游依赖列表<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:32 <br>
     * @Version： V2.0.2<br>
     */
    public TaskAllDependListDto upDependList(String taskCode, String bizDate) {
        DependPeriodTaskDto crunTask = getDependPeriodTaskDto(taskCode, bizDate);
        Set<DependPeriodTaskDto> dependTaskSet = buildDependTaskData(crunTask, bizDate);
        dependTaskSet.remove(crunTask);
        return new TaskAllDependListDto().setDependPeriodTaskDtoList(new ArrayList<>(dependTaskSet));
    }

    /*
     * @Method: buildDependTaskData <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：构建指定任务编码和业务日期的上游依赖列表<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:32 <br>
     * @Version： V2.0.2<br>
     */
    public Set<DependPeriodTaskDto> buildDependTaskData(DependPeriodTaskDto crunTask, String bizDate) {
        log.info("构建指定任务编码和业务日期的上游依赖列表,任务编码:{},业务日期:{}",crunTask.getTaskCode(),bizDate);
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        dependTaskSet.add(crunTask);
        dependTaskSet.addAll(buildDependJobList(crunTask, bizDate));
        dependTaskSet.addAll(buildDependTaskList(crunTask, bizDate));
        return dependTaskSet;
    }

    /*
     * @Method: buildDependJobList <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：获取指定任务的上游作业依赖数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:33 <br>
     * @Version： V2.0.2<br>
     */
    private Set<DependPeriodTaskDto> buildDependJobList(DependPeriodTaskDto crunTask, String bizDate) {
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        if (CollectionUtil.isNotEmpty(crunTask.getDependJobList())) {
            for (String jobCode : crunTask.getDependJobList()) {
                DependPeriodTaskDto dependPeriodTaskDto = getLastTaskForJob(jobCode, bizDate);
                if (dependPeriodTaskDto != null) {
                    dependTaskSet.addAll(buildDependTaskData(dependPeriodTaskDto, bizDate));
                }
            }
        }
        return dependTaskSet;
    }

    /*
     * @Method: buildDependTaskList <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：获取指定任务的下游作业依赖数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/25 16:33 <br>
     * @Version： V2.0.2<br>
     */
    private Set<DependPeriodTaskDto> buildDependTaskList(DependPeriodTaskDto crunTask, String bizDate) {
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        if (CollectionUtil.isNotEmpty(crunTask.getDependTaskList())) {
            for (String taskCode : crunTask.getDependTaskList()) {
                DependPeriodTaskDto dependPeriodTaskDto = getDependPeriodTaskDto(taskCode, bizDate);
                dependTaskSet.addAll(buildDependTaskData(dependPeriodTaskDto, bizDate));
            }
        }
        return dependTaskSet;
    }

    /*
     * @Method: downDependChat <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.TaskAllDependDto <br>
     * @Description：周期任务实例下游依赖图<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:17 <br>
     * @Version： V2.0.2<br>
     */
    public TaskAllDependDto downDependChat(String taskCode, String bizDate, String showType) {
        log.info("周期任务实例下游依赖图,任务编码:{},业务日期:{}",taskCode,bizDate);
        DependPeriodTaskDto crunTask = getDependPeriodTaskDto(taskCode, bizDate);
        TaskAllDependDto taskAllDependDto = new TaskAllDependDto(crunTask.getNodeName());
        buildDownDependChatData(showType, crunTask, crunTask, bizDate, taskAllDependDto);
        return taskAllDependDto;
    }

    /*
     * @Method: buildDownDependChatData <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建指定任务下游依赖数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:19 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDownDependChatData(String showType, DependPeriodTaskDto rootPeriodTask,
                                         DependPeriodTaskDto crunTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        if ("ALL_DEPEND".equals(showType) || isShowDownDepend(rootPeriodTask, crunTask)) {
            log.info("构建指定任务下游依赖数据,当前任务编码:{},业务日期:{}",crunTask.getTaskCode(),bizDate);
            buildTaskNode(crunTask, taskAllDependDto);
            buildDownDependJobLike(showType, rootPeriodTask, crunTask, bizDate, taskAllDependDto);
            buildDownDependTaskLike(showType, rootPeriodTask, crunTask, bizDate, taskAllDependDto);
        }
    }

    private boolean isShowDownDepend(DependPeriodTaskDto rootPeriodTask, DependPeriodTaskDto crunTask) {
        return rootPeriodTask.getTaskCode().equals(crunTask.getTaskCode())
                || crunTask.getDependTaskList().contains(rootPeriodTask.getTaskCode())
                || crunTask.getDependJobList().contains(rootPeriodTask.getJobCode());
    }

    /*
     * @Method: buildDownDependJobLike <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建依赖图作业节点与节点关系数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:19 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDownDependJobLike(String showType, DependPeriodTaskDto rootPeriodTask,
                                        DependPeriodTaskDto crunTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        List<PeriodTask> crunJobTaskList = qryTaskListInJob(crunTask.getJobCode(), bizDate);
        List<String> sortTaskCodes = sortByDependTask(crunJobTaskList);
        if (sortTaskCodes.indexOf(crunTask.getTaskCode()) == (crunJobTaskList.size() - 1)) {
            List<PeriodTask> periodTaskList = queryListByDependJob(crunTask.getJobCode(), bizDate);
            if (CollectionUtil.isNotEmpty(periodTaskList)) {
                for (PeriodTask downDependPeriodTask : periodTaskList) {
                    buildDownNodeLike(showType, rootPeriodTask, crunTask, dependPeriodTaskDtoConverter.toNodeInfo(downDependPeriodTask), bizDate, taskAllDependDto);
                }
            }
        }
    }

    /*
     * @Method: buildDownNodeLike <br>
     * @Param: [crunTask, downDependTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建依赖图节点与节点关系数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:18 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDownNodeLike(String showType, DependPeriodTaskDto rootPeriodTask,
                                   DependPeriodTaskDto crunTask, DependPeriodTaskDto downDependTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        DependRelationDto dependRelationDto = new DependRelationDto(crunTask.getNodeName(), downDependTask.getNodeName());
        if (!taskAllDependDto.getLinks().contains(dependRelationDto)) {
            taskAllDependDto.getLinks().add(dependRelationDto);
        }
        buildDownDependChatData(showType, rootPeriodTask, downDependTask, bizDate, taskAllDependDto);
    }

    /*
     * @Method: buildDownDependTaskLike <br>
     * @Param: [crunTask, bizDate, taskAllDependDto] <br>
     * @Return: void <br>
     * @Description：构建依赖图任务节点与其他节点关系数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:17 <br>
     * @Version： V2.0.2<br>
     */
    private void buildDownDependTaskLike(String showType, DependPeriodTaskDto rootPeriodTask,
                                         DependPeriodTaskDto crunTask, String bizDate, TaskAllDependDto taskAllDependDto) {
        List<PeriodTask> periodTaskList = queryListByDependTask(crunTask.getTaskCode(), bizDate);
        if (CollectionUtil.isNotEmpty(periodTaskList)) {
            for (PeriodTask downDependTask : periodTaskList) {
                buildDownNodeLike(showType, rootPeriodTask, crunTask, dependPeriodTaskDtoConverter.toNodeInfo(downDependTask), bizDate, taskAllDependDto);
            }
        }
    }

    /*
     * @Method: downDependList <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: com.hex.ds.hdrs.period.task.dto.depend.TaskAllDependListDto <br>
     * @Description：周期任务实例下游依赖列表<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:14 <br>
     * @Version： V2.0.2<br>
     */
    public TaskAllDependListDto downDependList(String taskCode, String bizDate) {
        log.info("周期任务实例下游依赖列表,任务编码:{},业务日期：{}",taskCode,bizDate);
        DependPeriodTaskDto crunTask = getDependPeriodTaskDto(taskCode, bizDate);
        Set<DependPeriodTaskDto> dependTaskDefSet = buildDownDependList(crunTask, bizDate);
        dependTaskDefSet.remove(crunTask);
        return new TaskAllDependListDto().setDependPeriodTaskDtoList(new ArrayList<>(dependTaskDefSet));
    }

    /*
     * @Method: buildDownDependList <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：构建周期任务实例下游依赖列表数据<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:14 <br>
     * @Version： V2.0.2<br>
     */
    private Set<DependPeriodTaskDto> buildDownDependList(DependPeriodTaskDto crunTask, String bizDate) {
        log.info("构建周期任务实例下游依赖列表数据,任务编码:{}，业务日期:{}",crunTask.getTaskCode(),bizDate);
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        dependTaskSet.add(crunTask);
        dependTaskSet.addAll(buildDownDependTaskList(crunTask, bizDate));
        dependTaskSet.addAll(buildDownDependJobList(crunTask, bizDate));
        return dependTaskSet;
    }

    /*
     * @Method: buildDownDependTaskList <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：根据指定任务编码编码查询依赖其的任务实例<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:15 <br>
     * @Version： V2.0.2<br>
     */
    private Set<DependPeriodTaskDto> buildDownDependTaskList(DependPeriodTaskDto crunTask, String bizDate) {
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        List<PeriodTask> downDependList = queryListByDependTask(crunTask.getTaskCode(), bizDate);
        for (PeriodTask downDependTask : downDependList) {
            dependTaskSet.addAll(buildDownDependList(dependPeriodTaskDtoConverter.toNodeInfo(downDependTask), bizDate));
        }
        return dependTaskSet;
    }

    /*
     * @Method: buildDownDependJobList <br>
     * @Param: [crunTask, bizDate] <br>
     * @Return: java.util.Set<com.hex.ds.hdrs.period.task.dto.depend.DependPeriodTaskDto> <br>
     * @Description：根据指定作业编码编码查询依赖其的任务实例（作业下游依赖即所属作业结束任务的下游依赖）<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:16 <br>
     * @Version： V2.0.2<br>
     */
    private Set<DependPeriodTaskDto> buildDownDependJobList(DependPeriodTaskDto crunTask, String bizDate) {
        Set<DependPeriodTaskDto> dependTaskSet = new HashSet<>();
        List<PeriodTask> crunJobTaskList = qryTaskListInJob(crunTask.getJobCode(), bizDate);
        List<String> sortTaskCodes = sortByDependTask(crunJobTaskList);
        if (sortTaskCodes.indexOf(crunTask.getTaskCode()) == (crunJobTaskList.size() - 1)) {
            List<PeriodTask> downDependList = queryListByDependJob(crunTask.getJobCode(), bizDate);
            for (PeriodTask downDependTask : downDependList) {
                dependTaskSet.addAll(buildDownDependList(dependPeriodTaskDtoConverter.toNodeInfo(downDependTask), bizDate));
            }
        }
        return dependTaskSet;
    }

    /*
     * @Method: queryListByDependJob <br>
     * @Param: [jobCode, bizDate] <br>
     * @Return: java.util.List<com.hex.ds.hdrs.period.task.po.PeriodTask> <br>
     * @Description：根据指定作业编码查询依赖其的任务实例<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:15 <br>
     * @Version： V2.0.2<br>
     */
    public List<PeriodTask> queryListByDependJob(String jobCode, String bizDate) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("dependJob", jobCode);
        paramMap.put("bizDate", bizDate);
        return periodTaskDao.qryTaskInfoList(paramMap);
    }

    /*
     * @Method: queryListByDependTask <br>
     * @Param: [taskCode, bizDate] <br>
     * @Return: java.util.List<com.hex.ds.hdrs.period.task.po.PeriodTask> <br>
     * @Description：根据指定任务编码查询依赖其的任务实例<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/26 10:14 <br>
     * @Version： V2.0.2<br>
     */
    public List<PeriodTask> queryListByDependTask(String taskCode, String bizDate) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("dependTask", taskCode);
        paramMap.put("bizDate", bizDate);
        return periodTaskDao.qryTaskInfoList(paramMap);
    }


    public TaskDependDto qryTask(String taskCode, String bizDate) {
        //任务编码
//        PeriodTaskDef periodTaskDef = periodTaskDefService.qryPeriodTaskDef(taskCode);
        Map map = new HashMap(16);
        map.put("taskCode", taskCode);
        map.put("bizDate", bizDate);
        List<PeriodTask> taskList = qryPeriodTaskList(map);
        TaskDependDto taskDependDto = new TaskDependDto();
        if(CollectionUtil.isNotEmpty(taskList)){
            taskDependDto.setId(taskList.get(0).getPkId()).setTaskCode(taskCode);
            taskDependDto.setStatus(taskList.get(0).getTaskStatus());
            taskDependDto.setPeriodTask(taskList.get(0));
        }
        return taskDependDto;
    }

    /**
     * @Method updateTaskStatus <br>
     * @Param
     * @Param periodTaskList
     * @Param taskStatus <br>
     * @Return void <br>
     * @Description 批量修改任务状态，勿删！<br>
     * @Author jian.qiao<br>
     * @Date 2024/2/20 10:14 <br>
     * @Version V1.0<br>
     */
    public void updateTaskStatus(List<PeriodTask> periodTaskList, String taskStatus) {
        log.info("外部调用批量修改任务状态，修改数据:{},状态为：{}",periodTaskList, taskStatus);
        try {
            this.dispatcherService.stopDispatcher();
            this.processorService.stopProcess();
            periodTaskList.forEach(periodTask -> {
                updateTaskStatusInBatch(periodTask, taskStatus);
                //删除待执行队列
                JobTask job = toDoManager.getJob(periodTask.getJobCode());
                if (job != null && periodTask.getBizDate().equals(job.getBizDate())) {
                    toDoManager.addJobToDeltaMap(job);
                    toDoManager.removeJob(job);
                }
                //删除可执行队列
                toRunManager.removeJob(periodTask, "Run_Remove");
            });
        } catch (Exception e) {
            log.error("更新任务状态失败:{}", e.getMessage());
        } finally {
            this.dispatcherService.continueDispatcher();
            this.processorService.continueProcess();
        }
    }
    /**
     * @Method updateRunning2ToDo <br>
     * @Param agentCode <br>
     * @Return  <br>
     * @Description Agent停用/重启时移除正在执行队列任务<br>
     * @Author jian.qiao<br>
     * @Date 2024/9/2 19:46 <br>
     * @Version V1.0<br>
     */
    public void updateRunning2ToDo(String agentCode) {
        PeriodTaskDto periodTaskDto = new PeriodTaskDto();
        periodTaskDto.setAgentCode(agentCode).setTaskStatus(Const.TASK_RUNNING);
        List<PeriodTask> taskList = this.queryList(periodTaskDto);
        for (PeriodTask periodTask : taskList){
            // 修改db状态为待处理
            Map<String,String> map = new HashMap<>();
            map.put("taskCode", periodTask.getTaskCode());
            map.put("bizDate", periodTask.getBizDate());
            map.put("taskStatus",Const.TASK_TODO_RUN);
            map.put("upTs",HdrsDateUtil.getCurrentTime());
            map.put("taskExecLog","重启/停用 Agent移除");
            this.updateTask(map);
            //移除正在执行中的任务
            runningManager.removeJob(periodTask, "重启/停用Agent移除");
            AppSession appSession = appManager.getValidAppSession(periodTask.getAppCode());
            appSession.delTaskSession(periodTask.getTaskCode());
        }

    }

}
